package org.tankwar.model;

import org.tankwar.type.Direction;
import org.tankwar.util.GlobalUtil;
import org.tankwar.view.GamePanel;
import java.awt.*;

public abstract class Tank implements GameComponent{
    public static int speedX = 6, speedY = 6; // 静态全局变量速度
    protected int step = GlobalUtil.rand.nextInt(10) + 5;
    public int width = 35, length = 35; // 坦克的全局大小，具有不可改变性
    protected Direction status = Direction.STOP; // 初始化状态为静止
    protected Direction direction = Direction.U; // 初始化方向为向上
    protected GamePanel tc;
    protected boolean good; // 玩家坦克还是敌方坦克
    protected int x, y; // 坦克当前的坐标
    protected int oldX, oldY; // 坦克上一步的坐标
    protected boolean live = true; // 初始化为活着
    protected int life; // 初始生命值
    protected boolean toL = false, toU = false, toR = false, toD = false; // 初始时坦克静止
    protected Image[] tankImages; // 坦克的图片

    public void drawTank(Graphics g) { // 共有的方法，画出坦克
        switch (direction) {
            // 根据方向选择坦克的图片
            case D:
                g.drawImage(tankImages[0], x, y, null);
                break;
            case U:
                g.drawImage(tankImages[1], x, y, null);
                break;
            case L:
                g.drawImage(tankImages[2], x, y, null);
                break;
            case R:
                g.drawImage(tankImages[3], x, y, null);
                break;
        }
    }

    public abstract void move(); // 抽象的坦克移动方法，敌方坦克会自动移动

    protected void baseMove() {
        this.oldX = x;
        this.oldY = y;
        switch (status) { // 选择移动方向
            case L:
                x -= speedX;
                break;
            case U:
                y -= speedY;
                break;
            case R:
                x += speedX;
                break;
            case D:
                y += speedY;
                break;
            case STOP:
                break;
        }
        if (this.status != Direction.STOP) {
            this.direction = this.status;
        }
        if (x < 0)
            x = 0;
        if (y < 40) // 防止走出规定区域
            y = 40;
        if (x + width > GamePanel.PANEL_WIDTH) // 超过区域则恢复到边界
            x = GamePanel.PANEL_WIDTH - width;
        if (y + length > GamePanel.PANEL_HEIGHT)
            y = GamePanel.PANEL_HEIGHT - length;
    }

    /**
     * 坦克开火的方法
     */
    public void fire() {
        if (!live)
            return;
        int x = this.x + width / 2 - Bullets.width / 2; // 开火位置
        int y = this.y + length / 2 - Bullets.length / 2;
        Bullets m = new Bullets(x, y + 2, good, direction, this.tc); // 没有给定方向时，向原来的方向发火
        tc.bullets.add(m);
    }

    protected void changToOldDir() {
        x = oldX;
        y = oldY;
    }

    @Override
    public Rectangle getRect() {
        return new Rectangle(x, y, width, length);
    }
    public boolean isLive() {
        return live;
    }

    public void setLive(boolean live) {
        this.live = live;
    }

    public boolean collideWithWall(BrickWall w) { // 碰撞到普通墙时
        if (this.live && this.getRect().intersects(w.getRect())) {
            this.changToOldDir(); // 转换到原来的方向上去
            return true;
        }
        return false;
    }

    public boolean collideWithWall(MetalWall w) { // 撞到金属墙
        if (this.live && this.getRect().intersects(w.getRect())) {
            this.changToOldDir();
            return true;
        }
        return false;
    }

    public boolean collideRiver(River r) { // 撞到河流的时候
        if (this.live && this.getRect().intersects(r.getRect())) {
            this.changToOldDir();
            return true;
        }
        return false;
    }

    /**
     * 撞到基地的处理方法
     * @param h 基地对象
     * @return boolean
     */
    public boolean collideHome(Home h) { // 撞到家的时候
        if (this.live && this.getRect().intersects(h.getRect())) {
            this.changToOldDir();
            return true;
        }
        return false;
    }

    /**
     * 撞到坦克的处理方法
     * @param tanks 另一个坦克
     * @return boolean
     */
    public<T extends Tank> boolean collideWithTanks(java.util.List<T> tanks) {// 撞到坦克时
        for (int i = 0; i < tanks.size(); i++) {
            Tank t = tanks.get(i);
            if (this != t) {
                if (this.live && t.isLive() && this.getRect().intersects(t.getRect())) {
                    this.changToOldDir();
                    t.changToOldDir();
                    return true;
                }
            }
        }
        return false;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void setToL(boolean toL) {
        this.toL = toL;
    }

    public void setToU(boolean toU) {
        this.toU = toU;
    }

    public void setToR(boolean toR) {
        this.toR = toR;
    }

    public void setToD(boolean toD) {
        this.toD = toD;
    }

    public boolean isGood() {
        return good;
    }
}
